/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package stendcontrol;

import bsh.EvalError;
import bsh.Interpreter;
import gui.ParamInterpreterInputer;
import java.io.OutputStream;
import java.io.PrintStream;
import javax.swing.JOptionPane;

/**
 *
 * @author minaev
 */
public class ResearchInterpreter extends Interpreter {

    DataTract dt;
    DataProcessor proc = new DataProcessor();
    ResearchInterpreter ri;
    PrintStream o_sys_out = System.out;
    OutputStream n_sys_out = null;

    public ResearchInterpreter(DataTract dt) {

        this.dt = dt;
        try {
            this.eval("import stendcontrol.Func;");
            this.eval("import stendcontrol.Param;");
            this.eval("import stendcontrol.Experiment;");
            this.eval("import stendcontrol.SclVal;");
            this.set("data", dt);
            this.set("sensors", dt.getSensorInformer());
            this.set("stend", dt.getStendControlApi());
            this.set("proc", proc);
            this.set("input", new ParamInterpreterInputer(this));
            this.set("T_FLOAT", ParamInterpreterInputer.T_FLOAT);
            this.set("T_INTEGER", ParamInterpreterInputer.T_INTEGER);
            this.set("TYPE_RESEARCH_NONE", StendControlAPI.TYPE_RESEARCH_NONE);
            this.set("TYPE_RESEARCH_DIST", StendControlAPI.TYPE_RESEARCH_DIST);
            this.set("TYPE_RESEARCH_TIME", StendControlAPI.TYPE_RESEARCH_TIME);
        } catch (EvalError ex) {
            StendLogger.log(StendLogger.MSG_ERROR, "Syntax error in start code"
                    + " ResearchInterpreter: " + ex.getMessage());
        }
    }

    public synchronized void setSysOut(OutputStream n_sys_out) {
        this.n_sys_out = n_sys_out;
    }

    private void applySysOut() {
        if (n_sys_out != null) {
            PrintStream ps = new PrintStream(n_sys_out);
            this.setOut(ps);
            this.setErr(ps);
        }
    }

    private void unapplySysOut() {
        if (n_sys_out != null) {
            this.setOut(o_sys_out);
            this.setErr(o_sys_out);
        }
    }

    public synchronized void startResearch(final Research rsch) throws EvalError {
        ri = this;
        this.set("exp", dt.getCurExp());
        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    startModalResearch(rsch);
                } catch (EvalError ex) {
                    StendLogger.log(StendLogger.MSG_ERROR, "Syntax error in "
                            + "line: " + ex.getErrorLineNumber()
                            + " research \""+rsch.getName()+"\": " 
                            + ex.getMessage());
                    JOptionPane.showMessageDialog(null, "Line: "
                            +ex.getErrorLineNumber()+" Error in syntax "
                            + "research \""
                            + rsch.getName()
                            + "\" :" + ex.getMessage(), "Syntax error",
                            JOptionPane.OK_OPTION);
                    
                }
            }
        });
        th.setPriority(6);
        th.start();
    }

    private synchronized void startModalResearch(final Research rsch) throws EvalError {
        applySysOut();
        this.eval(rsch.getCode());
        unapplySysOut();
    }
//    private ArrayList<Param> inputs = new ArrayList<>();
//    private ArrayList<String> var_names = new ArrayList<>();
//    private ArrayList<Integer> var_types = new ArrayList<>();
//    public final int T_INTEGER = 0;
//    public final int T_FLOAT = 1;
//
//    /**
//     * Объявление параметра ввода
//     *
//     * @param name - имя, отображаемое для ввода
//     * @param type - тип параметра T_INTEGER
//     * @param var_name
//     * @param def
//     */
//    public void input(String name, int type, String var_name, double def) {
//        inputs.add(new Param(name, Param.P_OTHER, def));
//        var_names.add(var_name);
//        var_types.add(type);
//    }
//
//    public void setInputs() {
//        setInputsWithNotClear();
//        input_fields.clear();
//        inputs.clear();
//        var_names.clear();
//        var_types.clear();
//    }
//    private JFrame input_frame;
//    private ArrayList<JTextField> input_fields = new ArrayList<>();
//
//    public void setInputsWithNotClear() {
//
//
//        java.awt.EventQueue.invokeLater(new Runnable() {
//            public void run() {
//                
//                input_frame = new JFrame("Ввод параметров");
//                addInputsComps(input_frame);
//                input_frame.setLocationRelativeTo(null);
//                //input_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//                input_frame.addWindowListener(new WindowListener() {
//                    @Override
//                    public void windowClosing(WindowEvent e) {
//                        e.getWindow().dispose();
//                    }
//
//                    @Override
//                    public void windowOpened(WindowEvent e) {
//                    }
//
//                    @Override
//                    public void windowClosed(WindowEvent e) {
//                    }
//
//                    @Override
//                    public void windowIconified(WindowEvent e) {
//                    }
//
//                    @Override
//                    public void windowDeiconified(WindowEvent e) {
//                    }
//
//                    @Override
//                    public void windowActivated(WindowEvent e) {
//                    }
//
//                    @Override
//                    public void windowDeactivated(WindowEvent e) {
//                    }
//                });
//                input_frame.setLayout(new java.awt.GridLayout(0, 2));
//                
//                input_frame.pack();
//
//                input_frame.setVisible(true);
//            }
//        });
//
//
//    }
//
//    private void addInputsComps(final Frame frm) {
//        for (int i = 0; i < inputs.size(); i++) {
//            frm.add(new JLabel(inputs.get(i).getName()));
//            input_fields.add(new JTextField(
//                    Double.toString(inputs.get(i).getValue())));
//            frm.add(input_fields.get(input_fields.size() - 1));
//        }
//        JButton ok_button = new JButton("OK");
//        ok_button.addActionListener(new ActionListener() {
//            @Override
//            public void actionPerformed(ActionEvent e) {
//                setInputsFromFields();
//                frm.dispose();
//            }
//        });
//        frm.add(ok_button, BorderLayout.SOUTH);
//    }
//
//    private void setInputsFromFields() {
//        for (int i = 0; i < input_fields.size(); i++) {
//            switch (var_types.get(i)) {
//                case T_INTEGER: {
//                    try {
//                        this.set(var_names.get(i),
//                                Integer.valueOf(input_fields.get(i).getText()));
//                    } catch (EvalError ex) {
//                        print("Невозможно установить целочисленную переменную "
//                                + var_names.get(i) + "со значением "
//                                + input_fields.get(i).getText() + " сообщение: "
//                                + ex.getMessage());
//                    }
//                    break;
//                }
//                case T_FLOAT: {
//                    try {
//                        this.set(var_names.get(i),
//                                Double.valueOf(input_fields.get(i).getText()));
//                    } catch (EvalError ex) {
//                        print("Невозможно установить дробную переменную "
//                                + var_names.get(i) + "со значением "
//                                + input_fields.get(i).getText() + " сообщение: "
//                                + ex.getMessage());
//                    }
//                    break;
//                }
//            }
//        }
//    }
}
